﻿using QLicense;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MultiDAQ_Analysis.License
{
    public static class LicenseManager
    {
        private static readonly string LICENSE_FILE_NAME = "license.lic";
        private static readonly string APP_NAME = "MultiDAQ_Analysis"; // 请修改为您的应用程序名称
        private static byte[] _publicKeyData;
        private static MyTimeLicense _cachedLicense;
        private static DateTime _lastCheckTime = DateTime.MinValue;
        private static LicenseStatus _cachedStatus = LicenseStatus.UNDEFINED;
        private static string _cachedMessage = "";

        /// <summary>
        /// 初始化许可证管理器
        /// </summary>
        /// <param name="publicKeyData">公钥证书数据</param>
        public static void Initialize(byte[] publicKeyData)
        {
            _publicKeyData = publicKeyData;
            // 初始化时清除缓存，强制重新检查
            ClearCache();
        }

        /// <summary>
        /// 清除缓存的许可证信息
        /// </summary>
        public static void ClearCache()
        {
            _cachedLicense = null;
            _lastCheckTime = DateTime.MinValue;
            _cachedStatus = LicenseStatus.UNDEFINED;
            _cachedMessage = "";
        }

        /// <summary>
        /// 检查许可证管理器是否已初始化
        /// </summary>
        /// <returns>是否已初始化</returns>
        public static bool IsInitialized()
        {
            return _publicKeyData != null && _publicKeyData.Length > 0;
        }

        /// <summary>
        /// 获取当前设备的唯一标识
        /// </summary>
        /// <returns>设备UID</returns>
        public static string GetDeviceUID()
        {
            try
            {
                return LicenseHandler.GenerateUID(APP_NAME);
            }
            catch (Exception ex)
            {
                // 如果生成失败，返回一个备用标识
                Console.WriteLine($"生成设备UID失败: {ex.Message}");
                return $"ERROR_{Environment.MachineName}_{DateTime.Now.Ticks}";
            }
        }




        /// <summary>
        /// 获取许可证文件路径（智能选择有权限的目录）
        /// </summary>
        /// <returns>许可证文件完整路径</returns>
        public static string GetLicenseFilePath()
        {
            // 尝试1: 应用程序目录
            try
            {
                string appDirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LICENSE_FILE_NAME);
                string testFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test_write.tmp");

                // 测试写权限
                File.WriteAllText(testFile, "test");
                File.Delete(testFile);

                return appDirPath; // 有权限，使用应用程序目录
            }
            catch
            {
                // 没有权限，使用用户目录
            }

            // 尝试2: 用户应用数据目录
            try
            {
                string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                string companyDir = Path.Combine(appDataPath, APP_NAME);

                if (!Directory.Exists(companyDir))
                {
                    Directory.CreateDirectory(companyDir);
                }

                return Path.Combine(companyDir, LICENSE_FILE_NAME);
            }
            catch
            {
                // 继续尝试其他位置
            }

            // 尝试3: 本地应用数据目录
            try
            {
                string localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                string companyDir = Path.Combine(localAppDataPath, APP_NAME);

                if (!Directory.Exists(companyDir))
                {
                    Directory.CreateDirectory(companyDir);
                }

                return Path.Combine(companyDir, LICENSE_FILE_NAME);
            }
            catch
            {
                // 继续尝试其他位置
            }

            // 尝试4: 用户文档目录
            try
            {
                string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                string companyDir = Path.Combine(documentsPath, APP_NAME);

                if (!Directory.Exists(companyDir))
                {
                    Directory.CreateDirectory(companyDir);
                }

                return Path.Combine(companyDir, LICENSE_FILE_NAME);
            }
            catch
            {
                // 最后备选方案
            }

            // 最后的备选方案：临时目录
            string tempPath = Path.GetTempPath();
            return Path.Combine(tempPath, APP_NAME + "_" + LICENSE_FILE_NAME);
        }

        // 同时更新LoadLicenseFromFile方法：

        /// <summary>
        /// 从本地文件加载许可证（改进的多路径搜索）
        /// </summary>
        /// <param name="filePath">文件路径（可选，默认使用智能搜索）</param>
        /// <returns>许可证字符串，如果文件不存在则返回null</returns>
        public static string LoadLicenseFromFile(string filePath = null)
        {
            try
            {
                // 如果指定了路径，直接尝试
                if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
                {
                    return File.ReadAllText(filePath, Encoding.UTF8);
                }

                // 搜索所有可能的位置
                var searchPaths = new List<string>();

                // 1. 默认路径
                try { searchPaths.Add(GetLicenseFilePath()); } catch { }

                // 2. 应用程序目录（兼容旧版本）
                try { searchPaths.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, LICENSE_FILE_NAME)); } catch { }

                // 3. 用户应用数据目录
                try
                {
                    string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                    searchPaths.Add(Path.Combine(appDataPath, APP_NAME, LICENSE_FILE_NAME));
                }
                catch { }

                // 4. 本地应用数据目录
                try
                {
                    string localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                    searchPaths.Add(Path.Combine(localAppDataPath, APP_NAME, LICENSE_FILE_NAME));
                }
                catch { }

                // 5. 用户文档目录
                try
                {
                    string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                    searchPaths.Add(Path.Combine(documentsPath, APP_NAME, LICENSE_FILE_NAME));
                }
                catch { }

                // 尝试从所有路径加载
                foreach (string path in searchPaths)
                {
                    try
                    {
                        if (File.Exists(path))
                        {
                            string content = File.ReadAllText(path, Encoding.UTF8);
                            if (!string.IsNullOrWhiteSpace(content))
                            {
                                Console.WriteLine($"许可证已从文件加载: {path}");
                                return content;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"尝试从 {path} 加载许可证失败: {ex.Message}");
                    }
                }

                Console.WriteLine("未找到有效的许可证文件");
                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"加载许可证文件失败: {ex.Message}");
                return null;
            }
        }

        // 更新LicenseFileExists方法：

        /// <summary>
        /// 验证许可证文件是否存在（多路径检查）
        /// </summary>
        /// <returns>许可证文件是否存在</returns>
        public static bool LicenseFileExists()
        {
            try
            {
                // 尝试从LoadLicenseFromFile加载
                string license = LoadLicenseFromFile();
                return !string.IsNullOrEmpty(license);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"检查许可证文件存在性失败: {ex.Message}");
                return false;
            }
        }


        /// <summary>
        /// 生成许可证字符串（服务器端使用）
        /// </summary>
        /// <param name="expireDate">过期时间</param>
        /// <param name="privateKeyData">私钥数据</param>
        /// <param name="keyPassword">私钥密码</param>
        /// <returns>许可证字符串</returns>
        public static string GenerateLicense(DateTime expireDate, byte[] privateKeyData, System.Security.SecureString keyPassword)
        {
            try
            {
                string deviceUID = GetDeviceUID();
                var license = new MyTimeLicense(APP_NAME, expireDate, deviceUID);
                return LicenseHandler.GenerateLicenseBASE64String(license, privateKeyData, keyPassword);
            }
            catch (Exception ex)
            {
                throw new Exception($"生成许可证失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 验证许可证字符串
        /// </summary>
        /// <param name="licenseString">许可证字符串</param>
        /// <param name="license">输出许可证对象</param>
        /// <param name="message">验证消息</param>
        /// <returns>验证是否成功</returns>
        public static bool ValidateLicense(string licenseString, out MyTimeLicense license, out string message)
        {
            license = null;
            message = "";

            try
            {
                if (_publicKeyData == null)
                {
                    message = "许可证管理器未初始化";
                    return false;
                }

                if (string.IsNullOrWhiteSpace(licenseString))
                {
                    message = "许可证字符串为空";
                    return false;
                }

                var licenseObj = LicenseHandler.ParseLicenseFromBASE64String(
                    typeof(MyTimeLicense),
                    licenseString,
                    _publicKeyData,
                    out LicenseStatus status,
                    out message
                );

                if (licenseObj is MyTimeLicense myLicense)
                {
                    license = myLicense;
                    return status == LicenseStatus.VALID;
                }

                message = "许可证格式无效";
                return false;
            }
            catch (Exception ex)
            {
                message = $"许可证验证失败: {ex.Message}";
                return false;
            }
        }

        /// <summary>
        /// 保存许可证到本地文件
        /// </summary>
        /// <param name="licenseString">许可证字符串</param>
        /// <param name="filePath">文件路径（可选，默认使用应用程序目录）</param>
        public static void SaveLicenseToFile(string licenseString, string filePath = null)
        {
            try
            {
                if (string.IsNullOrEmpty(filePath))
                {
                    filePath = GetLicenseFilePath();
                }

                // 确保目录存在
                string directory = Path.GetDirectoryName(filePath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                File.WriteAllText(filePath, licenseString);
                Console.WriteLine($"许可证已保存到: {filePath}");

                // 清除缓存，强制重新加载
                ClearCache();
            }
            catch (Exception ex)
            {
                throw new Exception($"保存许可证文件失败: {ex.Message}", ex);
            }
        }


        /// <summary>
        /// 删除本地许可证文件
        /// </summary>
        /// <param name="filePath">文件路径（可选，默认使用应用程序目录）</param>
        public static void DeleteLicenseFile(string filePath = null)
        {
            try
            {
                if (string.IsNullOrEmpty(filePath))
                {
                    filePath = GetLicenseFilePath();
                }

                if (File.Exists(filePath))
                {
                    File.Delete(filePath);
                    Console.WriteLine($"许可证文件已删除: {filePath}");

                    // 清除缓存
                    ClearCache();
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"删除许可证文件失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 检查当前应用程序的许可证状态
        /// </summary>
        /// <param name="license">输出许可证信息</param>
        /// <param name="message">状态消息</param>
        /// <returns>是否有有效许可证</returns>
        public static bool CheckCurrentLicense(out MyTimeLicense license, out string message)
        {
            license = null;
            message = "";

            try
            {
                string licenseString = LoadLicenseFromFile();
                if (string.IsNullOrEmpty(licenseString))
                {
                    message = "未找到许可证文件";
                    return false;
                }

                return ValidateLicense(licenseString, out license, out message);
            }
            catch (Exception ex)
            {
                message = $"检查许可证时发生错误: {ex.Message}";
                return false;
            }
        }

        /// <summary>
        /// 获取当前许可证状态
        /// </summary>
        /// <param name="forceRefresh">是否强制刷新，不使用缓存</param>
        /// <returns>许可证状态</returns>
        public static LicenseStatus GetLicenseStatus(bool forceRefresh = false)
        {
            try
            {
                // 检查是否需要刷新缓存（超过5分钟或强制刷新）
                if (forceRefresh ||
                    _lastCheckTime == DateTime.MinValue ||
                    (DateTime.Now - _lastCheckTime).TotalMinutes > 5)
                {
                    RefreshLicenseCache();
                }

                return _cachedStatus;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取许可证状态失败: {ex.Message}");
                return LicenseStatus.UNDEFINED;
            }
        }

        /// <summary>
        /// 获取当前许可证信息
        /// </summary>
        /// <param name="forceRefresh">是否强制刷新，不使用缓存</param>
        /// <returns>许可证信息，如果无效则返回null</returns>
        public static MyTimeLicense GetLicenseInfo(bool forceRefresh = false)
        {
            try
            {
                // 检查是否需要刷新缓存
                if (forceRefresh ||
                    _lastCheckTime == DateTime.MinValue ||
                    (DateTime.Now - _lastCheckTime).TotalMinutes > 5)
                {
                    RefreshLicenseCache();
                }

                return _cachedLicense;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取许可证信息失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取最后一次检查的状态消息
        /// </summary>
        /// <returns>状态消息</returns>
        public static string GetLastStatusMessage()
        {
            return _cachedMessage;
        }

        /// <summary>
        /// 获取最后一次检查的时间
        /// </summary>
        /// <returns>检查时间</returns>
        public static DateTime GetLastCheckTime()
        {
            return _lastCheckTime;
        }

        /// <summary>
        /// 刷新许可证缓存
        /// </summary>
        private static void RefreshLicenseCache()
        {
            try
            {
                if (!IsInitialized())
                {
                    _cachedStatus = LicenseStatus.UNDEFINED;
                    _cachedLicense = null;
                    _cachedMessage = "许可证管理器未初始化";
                    _lastCheckTime = DateTime.Now;
                    return;
                }

                string licenseString = LoadLicenseFromFile();
                if (string.IsNullOrEmpty(licenseString))
                {
                    _cachedStatus = LicenseStatus.INVALID;
                    _cachedLicense = null;
                    _cachedMessage = "未找到许可证文件";
                    _lastCheckTime = DateTime.Now;
                    return;
                }

                // 验证许可证
                var licenseObj = LicenseHandler.ParseLicenseFromBASE64String(
                    typeof(MyTimeLicense),
                    licenseString,
                    _publicKeyData,
                    out LicenseStatus status,
                    out string message
                );

                _cachedStatus = status;
                _cachedMessage = message;
                _lastCheckTime = DateTime.Now;

                if (licenseObj is MyTimeLicense myLicense && status == LicenseStatus.VALID)
                {
                    _cachedLicense = myLicense;
                }
                else
                {
                    _cachedLicense = null;
                }
            }
            catch (Exception ex)
            {
                _cachedStatus = LicenseStatus.UNDEFINED;
                _cachedLicense = null;
                _cachedMessage = $"刷新许可证缓存失败: {ex.Message}";
                _lastCheckTime = DateTime.Now;
                Console.WriteLine(_cachedMessage);
            }
        }

        /// <summary>
        /// 激活许可证（保存许可证字符串并验证）
        /// </summary>
        /// <param name="licenseString">许可证字符串</param>
        /// <param name="message">操作消息</param>
        /// <returns>是否激活成功</returns>
        public static bool ActivateLicense(string licenseString, out string message)
        {
            message = "";

            try
            {
                // 首先验证许可证
                if (!ValidateLicense(licenseString, out MyTimeLicense license, out message))
                {
                    return false;
                }

                // 验证通过，保存许可证文件
                SaveLicenseToFile(licenseString);

                // 强制刷新缓存
                RefreshLicenseCache();

                message = "许可证激活成功";
                return true;
            }
            catch (Exception ex)
            {
                message = $"激活许可证失败: {ex.Message}";
                return false;
            }
        }

        /// <summary>
        /// 检查许可证是否即将过期（默认30天内）
        /// </summary>
        /// <param name="warningDays">提前警告天数</param>
        /// <returns>是否即将过期</returns>
        public static bool IsLicenseExpiringSoon(int warningDays = 30)
        {
            try
            {
                var license = GetLicenseInfo();
                if (license?.ExpireDate == null)
                {
                    return false;
                }

                TimeSpan remaining = license.ExpireDate.Value - DateTime.Now;
                return remaining.TotalDays <= warningDays && remaining.TotalDays > 0;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取许可证剩余天数
        /// </summary>
        /// <returns>剩余天数，如果许可证无效返回-1</returns>
        public static int GetRemainingDays()
        {
            try
            {
                var license = GetLicenseInfo();
                if (license?.ExpireDate == null)
                {
                    return -1;
                }

                TimeSpan remaining = license.ExpireDate.Value - DateTime.Now;
                return (int)Math.Ceiling(remaining.TotalDays);
            }
            catch
            {
                return -1;
            }
        }

        /// <summary>
        /// 获取应用程序名称
        /// </summary>
        /// <returns>应用程序名称</returns>
        public static string GetAppName()
        {
            return APP_NAME;
        }
    }
}